﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GestionePolveriLib.BL;
using GestionePolveri2.DAL;

namespace GestionePolveriLib.Facades.Extensions
{
    public static class FacadeExtensions
    {
        public static Colore CreateColore(this ColoriFacade facade, string codiceColore, string descrizione, string note, FamigliaColore famiglia)
        {
            Colore retValue = null;

            retValue = new Colore();
            retValue.CodiceColore = codiceColore;
            retValue.Descrizione = descrizione;
            retValue.Note = note;
            retValue.Famiglia = famiglia;

            return retValue;
        }

        public static Polvere CreatePolvere(this PolvereFacade facade, string codicePolvere, string descrizione, string note, Fornitore fornitore)
        {
            Polvere retValue = null;

            retValue = new Polvere();
            retValue.CodicePolvere = codicePolvere;
            retValue.Descrizione = descrizione;
            retValue.Note = note;
            retValue.ScortaMinima = 0;
            retValue.IsCodiceCustom = false;
            retValue.Fornitore = fornitore;

            return retValue;
        }

        public static ComposizioneColoreExt CreateComposizioneColore(this ComposizioneColoreFacadeExt facade, Colore colore, List<PolvereExt> polveri)
        {
            ComposizioneColoreExt retValue = null;

            retValue = new ComposizioneColoreExt();
            retValue.Colore = colore;
            retValue.Polveri = polveri;

            return retValue;
        }

        public static Movimento CreateMovimento(this MovimentiFacade facade, 
                                                string tipomov,
                                                double giacenza, 
                                                int idPolvere,
                                                DateTime dataMovimento, int? idCausaleScarico, int idCausale, 
                                                short idFormato,
                                                int idImpianto, string note, double numeroScatole,
                                                double quantita,
                                                bool giacenzaInsufficienteFlag, bool sottoScortaFlag,
                                                Lotto lotto
                                                )
        {
            Movimento retValue = null;

            retValue = new Movimento();

            if (tipomov == "C")
            {
                retValue.IDCausale = idCausale;
                retValue.DataMovimento = dataMovimento;
                retValue.IDPolvere = idPolvere;
                retValue.IDFormato = idFormato;
                retValue.NumScatole = numeroScatole;
                retValue.Quantita = quantita;
                //retValue.Giacenza = quantita;
                //retValue.Valore = quantita;
                retValue.Note = note;
                retValue.IDOperatore = Guid.Parse("806885CF-754D-4D94-AD77-A7D1759AAB16");
            }
            else
            {
                retValue.IDCausale = idCausale;
                retValue.IDCausaleScarico = (idCausaleScarico == 0 ? null : idCausaleScarico);
                retValue.DataMovimento = dataMovimento;
                retValue.IDPolvere = idPolvere;         
                retValue.IDFormato = idFormato;
                retValue.NumScatole = numeroScatole;
                retValue.Quantita = quantita;
                retValue.Note = note;
                retValue.IDOperatore = Guid.Parse("806885CF-754D-4D94-AD77-A7D1759AAB16");

                //
                retValue.IDImpianto = idImpianto;               
                retValue.GiacenzaInsufficienteFlag = giacenzaInsufficienteFlag;
                retValue.SottoScortaFlag = sottoScortaFlag;
            }

            return retValue;
        }

        public static Lotto CreateLotto(this LottoFacade facade, string codiceLotto, string numDDT, DateTime dataDDT, 
                                                                 double giacenza, double prezzoUnitario, int idPolvere)
        {
            Lotto retValue = null;

            retValue = new Lotto();

            retValue.CodLotto = codiceLotto;
            retValue.NumDdt = numDDT;
            retValue.DataDdt = dataDDT;
            retValue.DataScadenzaLotto = dataDDT.AddMonths(6);
            retValue.Giacenza = giacenza;
            retValue.PrezzoUnitario = prezzoUnitario;
            retValue.Valore = retValue.Giacenza * retValue.PrezzoUnitario;
            retValue.IDPolvere = idPolvere;

            return retValue;
        }

        public static List<Colore> GetColoriForFilter(this ColoriFacade facade)
        {
            List<Colore> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagColori
                          orderby x.CodiceColore
                          select new Colore
                          {
                              ID = x.IDColore,
                              CodiceColore = x.CodiceColore
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Colore> GetColoriForAssociaPolvere(this ColoriFacade facade)
        {
            List<Colore> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagColori
                          orderby x.CodiceColore
                          select new Colore
                          {
                              ID = x.IDColore,
                              CodiceColore = x.CodiceColore,
                              Descrizione = x.Descrizione,
                              Note = x.Note,
                              Famiglia = (from y in context.AnagFamiglie
                                          where y.IDFamiglia == x.IDFamiglia
                                          select new FamigliaColore
                                          {
                                              ID = y.IDFamiglia,
                                              Descrizione = y.Descrizione
                                          }).FirstOrDefault()
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Colore> GetColoriByFamigliaForFilter(this ColoriFacade facade, FamigliaColore famiglia)
        {
            List<Colore> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagColori
                          where x.AnagFamiglie.IDFamiglia == famiglia.ID
                          orderby x.CodiceColore
                          select new Colore
                          {
                              ID = x.IDColore,
                              CodiceColore = x.CodiceColore
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Polvere> GetPolveriForFilter(this PolvereFacade facade)
        {
            List<Polvere> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagPolveri
                          orderby x.CodicePolvere
                          select new Polvere
                          {
                              ID = x.IDPolvere,
                              CodicePolvere = x.CodicePolvere
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<PolvereExt> GetPolveriForAssociaPolvere(this PolvereFacade facade)
        {
            List<PolvereExt> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagPolveri
                          orderby x.CodicePolvere
                          select new PolvereExt
                          {
                              Note = x.Note,
                              Base = false,
                              Venatura = false,
                              ID = x.IDPolvere,
                              CodicePolvere = x.CodicePolvere,
                              Descrizione = x.Descrizione,
                              Fornitore = (from y in context.AnagFornitori
                                           where y.IDFornitore == x.IDFornitore
                                           select new Fornitore
                                           {
                                               ID = y.IDFornitore,
                                               Descrizione = y.Descrizione,
                                               Note = y.Note
                                           }).FirstOrDefault()
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Polvere> GetPolveriForCS(this PolvereFacade facade)
        {
            List<Polvere> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagPolveri
                          orderby x.CodicePolvere
                          select new Polvere
                          {
                              ID = x.IDPolvere,
                              CodicePolvere = x.CodicePolvere,
                              Descrizione=x.Descrizione,
                              Note=x.Note,
                              ScortaMinima=x.ScortaMinima,
                              Fornitore = (from f in context.AnagFornitori 
                                           where f.IDFornitore == x.IDFornitore 
                                           select new Fornitore { ID = f.IDFornitore, Descrizione = f.Descrizione }).FirstOrDefault(),
                              IsCodiceCustom = x.IsCodiceCustom
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Polvere> GetPolveriForCS2(this PolvereFacade facade)
        {
            List<Polvere> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = (from x in context.AnagPolveri
                          join ll in context.Lotti on x.IDPolvere equals ll.IDPolvere
                          orderby x.CodicePolvere
                          select new Polvere
                          {
                              ID = x.IDPolvere,
                              CodicePolvere = x.CodicePolvere,
                              Descrizione = x.Descrizione,
                              Note = x.Note,
                              ScortaMinima = x.ScortaMinima,
                              Fornitore = (from f in context.AnagFornitori
                                           where f.IDFornitore == x.IDFornitore
                                           select new Fornitore { ID = f.IDFornitore, Descrizione = f.Descrizione }).FirstOrDefault(),
                              IsCodiceCustom = x.IsCodiceCustom
                          }).Distinct();

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Polvere> GetPolveriForCSMinimal(this PolvereFacade facade)
        {
            List<Polvere> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagPolveri
                          orderby x.CodicePolvere
                          select new Polvere
                          {
                              ID = x.IDPolvere,
                              CodicePolvere = x.CodicePolvere,
                              QuantitaImpegnata = (from pr in context.Prenotazioni where pr.IDPolvere == x.IDPolvere where !pr.IsAnnullata select pr.Quantita).Sum()
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Lotto> GetLottiForFilter(this LottoFacade facade)
        {
            List<Lotto> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.Lotti
                          //where x.Giacenza != 0
                          orderby x.CodLotto
                          select new Lotto
                          {
                              IDLotto = x.IDLotto,
                              CodLotto = x.CodLotto
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static List<Fornitore> GetFornitoriForFilter(this FornitoriFacade facade)
        {
            List<Fornitore> retValue = null;

            try
            {
                GestionePolveriEntities context = facade.GetContext();
                var obj = from x in context.AnagFornitori
                          orderby x.Descrizione
                          select new Fornitore
                          {
                              ID = x.IDFornitore,
                              Descrizione = x.Descrizione
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public static int LookUpPolvere(this PolvereFacade facade, string codicePolvere)
        {
            int retValue = -1;

            if (codicePolvere.Equals("xxxx", StringComparison.InvariantCultureIgnoreCase))
            {
                // codice XXXX
                // quello che deve cercare è: codice polvere + codice polvere reale => "xxxx - codPolvere"
            }
            
            /*
             1) cerco il codice polvere (nel db o nel dictionary)
             2) se trovo il codice polvere, lo restituisco e lo uso
             3) se non lo trovo, lo creo e lo restituisco, e lo uso
                          
             */

            return retValue;
        }
    }
}
